import 'dart:async';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:path_provider/path_provider.dart';
import 'package:extended_image/extended_image.dart';
import 'package:x3_component_core/x3_component_core.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';

class BaseImageHeroComponent extends StatefulWidget {
  final Animation animation;

  final String hero;

  final Color backgroundColor;

  final String imageUrl;

  final List<dynamic> imageList;

  final String placeholderImage;

  final String currentShowImageUrl;

  const BaseImageHeroComponent({Key key, @required this.animation, @required this.hero, @required this.imageUrl, @required this.currentShowImageUrl, @required this.imageList, @required this.placeholderImage, this.backgroundColor}) : super(key: key);

  @override
  _BaseImageHeroComponentState createState() => _BaseImageHeroComponentState();
}

class _BaseImageHeroComponentState extends State<BaseImageHeroComponent> {
  List<dynamic> _imageList;

  int _currentIndex;

  @override
  void initState() {
    this._imageList = this._initImageList();
    this._currentIndex = this._imageList.indexOf(BaseUtils.initImageUrl(widget.imageUrl));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap: () => Navigator.of(context).pop(),
        child: Hero(
          tag: widget.hero,
          child: Stack(
            children: [
              AnimatedOpacity(opacity: 0.0, duration: Duration(milliseconds: 0), child: _buildHiddenWidget()),
              Container(width: double.infinity, height: double.infinity, color: widget.backgroundColor ?? (_getBackgroundColor() ?? Colors.transparent), child: _buildGesturePageViewWidget()),
            ],
          ),
        ));
  }

  Widget _buildHiddenWidget() {
    bool isVideo = BaseUtils.isVideoFile(widget.currentShowImageUrl);
    if (isVideo) return FijkVideoPlayerScreen(videoUrl: widget.currentShowImageUrl);
    return _buildHiddenImageWidget();
  }

  Widget _buildHiddenImageWidget() {
    return ExtendedImage.network(widget.currentShowImageUrl, fit: BoxFit.contain, mode: ExtendedImageMode.gesture, initGestureConfigHandler: _initGestureConfigHandler);
  }

  Widget _buildGesturePageViewWidget() {
    return ExtendedImageGesturePageView.builder(
      itemBuilder: (BuildContext context, int index) {
        dynamic imageUrl = this._imageList[index];
        return ExtendedImageGesturePageViewItemBuilder(index: index, itemLink: imageUrl, backgroundColor: widget.backgroundColor);
      },
      itemCount: this._imageList.length,
      onPageChanged: (int index) => _currentIndex = index,
      controller: new ExtendedPageController(initialPage: _currentIndex),
      scrollDirection: Axis.horizontal,
    );
  }

  List<dynamic> _initImageList() {
    List<dynamic> imageList = [];
    if (widget.imageList == null || widget.imageList.length == 0) {
      String initCurrentImageUrl = BaseUtils.initImageUrl(widget.imageUrl);
      imageList.add(initCurrentImageUrl);
    } else {
      imageList = widget.imageList.map((e) => BaseUtils.initImageUrl(e)).toList();
    }
    return imageList;
  }

  GestureConfig _initGestureConfigHandler(ExtendedImageState state) {
    return GestureConfig(inPageView: true, initialScale: 1.0, cacheGesture: false);
  }

  /// png 图片用白底背景
  Color _getBackgroundColor() {
    if (widget.imageUrl != null && widget.imageUrl.contains(".")) {
      String _suffix = widget.imageUrl.split(".").last;
      if (_suffix.isNotEmpty && (_suffix == "png" || _suffix == "PNG")) return Colors.white;
    }
    return null;
  }
}

class ExtendedImageGesturePageViewItemBuilder extends StatefulWidget {
  final int index;
  final String itemLink;
  final Color backgroundColor;

  const ExtendedImageGesturePageViewItemBuilder({Key key, @required this.index, @required this.itemLink, @required this.backgroundColor}) : super(key: key);

  @override
  State<ExtendedImageGesturePageViewItemBuilder> createState() => _ExtendedImageGesturePageViewItemBuilderState();
}

class _ExtendedImageGesturePageViewItemBuilderState extends State<ExtendedImageGesturePageViewItemBuilder> {
  final StreamController<int> indexController = StreamController<int>.broadcast();

  @override
  void dispose() {
    super.dispose();
    indexController.close();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: double.infinity,
      color: widget.backgroundColor ?? (_getBackgroundColor() ?? Colors.transparent),
      child: buildStack(),
    );
  }

  Widget buildStack() {
    return Stack(
      alignment: Alignment.bottomCenter,
      children: [
        buildMain(),
        Positioned(bottom: 80, child: buildDownloadButton()),
      ],
    );
  }

  Widget buildMain() {
    bool isVideo = BaseUtils.isVideoFile(widget.itemLink);
    if (isVideo) return FijkVideoPlayerScreen(videoUrl: widget.itemLink);
    return Container(
      alignment: Alignment.center,
      padding: const EdgeInsets.all(5.0),
      child: ExtendedImage.network(widget.itemLink, fit: BoxFit.contain, mode: ExtendedImageMode.gesture, initGestureConfigHandler: _initGestureConfigHandler),
    );
  }

  /// 下载按钮
  Widget buildDownloadButton() {
    return GestureDetector(behavior: HitTestBehavior.translucent, onTap: onDownloadEvent, child: buildStreamBuilder());
  }

  /// 当前页签的流
  Widget buildStreamBuilder() {
    return Container(
      width: 120,
      height: 40,
      child: StreamBuilder(
        stream: indexController.stream,
        initialData: 0,
        builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
          bool isVideo = BaseUtils.isVideoFile(widget.itemLink);
          return BaseButton(text: isVideo ? '下载视频' : '下载原图', fill: false, width: 120, height: 40);
        },
      ),
    );
  }

  GestureConfig _initGestureConfigHandler(ExtendedImageState state) {
    return GestureConfig(inPageView: true, initialScale: 1.0, cacheGesture: false);
  }

  /// 下载资源
  void onDownloadEvent() async {
    bool requiredPermission = await this._handlerPermission();
    if (!requiredPermission) return;
    bool isVideo = BaseUtils.isVideoFile(widget.itemLink);
    bool state = false;
    if (!isVideo) state = await downloadImage();
    if (isVideo) state = await downloadFile();
    if (state) BaseUtils.showToast("下载成功");
  }

  /// 下载情况回调
  Future<bool> _handlerPermission() async {
    PermissionStatus status = await Permission.storage.status;
    if (status.isGranted == true) {
      return Future.value(true);
    }
    Map<Permission, PermissionStatus> statuses = await [Permission.storage].request();
    if (statuses[Permission.storage].isGranted == true) {
      return Future.value(true);
    }
    return Future.value(false);
  }

  /// 下载图片
  Future<bool> downloadImage() async {
    BaseComponentUtils.showLoadingDialog(context, hint: "请等待");
    Uint8List uint8list = await getUint8List();
    BaseComponentUtils.hideLoadingDialog(context);
    bool result = await saveImageList(uint8list);
    return result;
  }

  /// 获取Uint8List数据 下载图片
  Future<Uint8List> getUint8List() async {
    try {
      var response = await Dio().get(widget.itemLink, options: Options(responseType: ResponseType.bytes));
      Uint8List uint8list = Uint8List.fromList(response.data);
      return uint8list;
    } catch (e) {
      print(e);
    }
    return null;
  }

  /// 下载视频
  ///下载文件到本地
  ///urlPath 文件Url
  ///savePath 本地保存位置
  ///downloadProgressCallBack 下载文件回调
  Future<bool> downloadFile() async {
    try {
      BaseComponentUtils.showLoadingDialog(context, hint: "正在下载");
      Dio dio = Dio();
      String urlPath = widget.itemLink;
      List<dynamic> items = urlPath.split('.');
      String savePath = await getPhoneLocalPath();
      String fileName = '${new DateTime.now().millisecondsSinceEpoch.toString()}.${items[items.length - 1]}';
      String storagePath = '$savePath/$fileName';
      Response response = await dio.download(urlPath, storagePath);
      BaseComponentUtils.hideLoadingDialog(context);
      if (response.statusCode == 200) {
        final result = await ImageGallerySaver.saveFile(storagePath);
        if (result != null) {
          String isSuccess = BaseUtils.getKeyData(result, 'isSuccess').toString();
          if (isSuccess == 'true') {
            return true;
          }
        }
      }
      return false;
    } catch (e) {
      print(e);
    }
    return null;
  }

  Future<bool> saveImageList(Uint8List uint8list) async {
    BaseComponentUtils.showLoadingDialog(context, hint: "正在下载");
    final AssetEntity entity = await PhotoManager.editor.saveImage(uint8list);
    BaseComponentUtils.hideLoadingDialog(context);
    return entity.exists;
  }

  ///  获取手机的存储目录路径
  ///  getExternalStorageDirectory() 获取的是  android 的外部存储 （External Storage）
  ///  getApplicationDocumentsDirectory 获取的是 ios 的Documents` or `Downloads` 目录
  Future<String> getPhoneLocalPath() async {
    final directory = Theme.of(context).platform == TargetPlatform.android ? await getExternalStorageDirectory() : await getApplicationDocumentsDirectory();
    return directory.path;
  }

  /// png 图片用白底背景
  Color _getBackgroundColor() {
    if (widget.itemLink != null && widget.itemLink.contains(".")) {
      String _suffix = widget.itemLink.split(".").last;
      if (_suffix.isNotEmpty && (_suffix == "png" || _suffix == "PNG")) return Colors.white;
    }
    return null;
  }
}
